home *** CD-ROM | disk | FTP | other *** search
/ 3D Images / 3D Images.iso / programs / amiga / mpegutils / tools / src / cyuv2ppm.c next >
C/C++ Source or Header  |  1995-01-12  |  7KB  |  251 lines

  1. /*************************************************************
  2. Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
  3. PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
  4. Group. If you use this software, you agree to the following: This
  5. program package is purely experimental, and is licensed "as is".
  6. Permission is granted to use, modify, and distribute this program
  7. without charge for any purpose, provided this license/ disclaimer
  8. notice appears in the copies.  No warranty or maintenance is given,
  9. either expressed or implied.  In no event shall the author(s) be
  10. liable to you or a third party for any special, incidental,
  11. consequential, or other damages, arising out of the use or inability
  12. to use the program for any purpose (or the loss of data), even if we
  13. have been advised of such possibilities.  Any public reference or
  14. advertisement of this source code should refer to it as the Portable
  15. Video Research Group (PVRG) code, and not by any author(s) (or
  16. Stanford University) name.
  17. *************************************************************/
  18. /*
  19. ************************************************************
  20. cyuv2ppm.c
  21.  
  22. This program converts component YUV files with a sampling ratio of
  23. 4:1:1 (the same pattern as MPEG 4:2:0; the files read from .Y .U .V by
  24. default) into a single raw ppm file.
  25.  
  26. The ppm description and files are part of Jef Poskanzer's PBMPLUS
  27. library.  This is just a short-cut program to do a simple RGB
  28. conversion.
  29.  
  30. -----
  31. Modifications by Son H. Le on 01-Sep-93
  32.   o replaced all exit(-1) with exit(0)
  33.   o added exit(0) after convertYUV2RGB()
  34.   o added #include <stdlib.h> and <string.h>
  35.   o added prototype convertYUV2RGB()
  36. ************************************************************
  37. */
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42.  
  43. #define PPM_MAGIC1 'P'
  44. #define PPM_MAGIC2 '3'
  45. #define RPPM_MAGIC2 '6'
  46. #define FIXNUM 16
  47.  
  48. #define FIX(a,b) ((int)((a)*(1<<(b))))
  49. #define UNFIX(a,b) ((a+(1<<(b-1)))>>(b))
  50.  
  51. /* Approximate 255 by 256 */
  52. #define ICCIRUV(x) (((x)<<8)/224)
  53. #define ICCIRY(x) ((((x)-16)<<8)/219)
  54.  
  55. #define CLIP(t) (((t)>255)?255:(((t)<0)?0:(t)))
  56. #define GETR(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
  57.                FIX(1.402,FIXNUM)*(v)),FIXNUM)
  58. #define GETG(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
  59.                FIX(-0.34414,FIXNUM)*(u)+\
  60.                FIX(-0.71414,FIXNUM)*(v)),FIXNUM)
  61. #define GETB(y,u,v) UNFIX((FIX(1.0,FIXNUM)*(y)+\
  62.                FIX(1.772,FIXNUM)*(u)),FIXNUM)
  63. char *suffix[3] = {".Y",".U",".V"};
  64.  
  65. void convertYUV2RGB(int cols,int rows,FILE *iny,FILE *inu,FILE *inv,
  66.                     FILE *out,int CCIR601);
  67.  
  68. void
  69. convertYUV2RGB(cols, rows, iny, inu, inv, out, CCIR601)
  70.      int cols,rows;
  71.      FILE *iny,*inu,*inv,*out;
  72.      int CCIR601;
  73. {
  74.   int i,j;
  75.   int y1,y2,y3,y4,u1,v1;
  76.   int temp;
  77.   unsigned char *temprgb1, *temprgb2, *tempy1, *tempy2, *tempu, *tempv;
  78.   unsigned char *rgb1p, *rgb2p, *y1p, *y2p, *up, *vp;
  79.  
  80.   fprintf(out,"%c%c\n%d %d\n%d\n",PPM_MAGIC1,RPPM_MAGIC2,cols,rows,255);
  81.   printf("input size: %dx%d\t output size: %dx%d\n",
  82.      cols,rows,cols,rows);
  83.  
  84.   temprgb1 = (unsigned char *) calloc(cols*3,sizeof(char));
  85.   temprgb2 = (unsigned char *) calloc(cols*3,sizeof(char));
  86.   tempy1 = (unsigned char *) calloc(cols,sizeof(char));
  87.   tempy2 = (unsigned char *) calloc(cols,sizeof(char));
  88.   tempu = (unsigned char *) calloc(cols>>1,sizeof(char));
  89.   tempv = (unsigned char *) calloc(cols>>1,sizeof(char));
  90.  
  91.   if ((rows&1)||(cols&1))
  92.     {
  93.       printf("rows and columns must be multiple of 2\n");
  94.       exit(0);
  95.     }
  96.   for(i=0;i<(rows>>1);i++)
  97.     {
  98.       fread(tempy1,1,cols*sizeof(char),iny);
  99.       fread(tempy2,1,cols*sizeof(char),iny);
  100.       fread(tempu,1,(cols>>1)*sizeof(char),inu);
  101.       fread(tempv,1,(cols>>1)*sizeof(char),inv);
  102.  
  103.       rgb1p = temprgb1;
  104.       rgb2p = temprgb2;
  105.       y1p = tempy1;
  106.       y2p = tempy2;
  107.       up = tempu;
  108.       vp = tempv;
  109.  
  110.       for(j=0;j<(cols>>1);j++)
  111.     {                      /* We use pel replication for interpolation */
  112.       y1 = *(y1p++);
  113.       y2 = *(y1p++);
  114.       y3 = *(y2p++);
  115.       y4 = *(y2p++);
  116.  
  117.       u1 = *(up++);
  118.       v1 = *(vp++);
  119.       u1 -=128;
  120.       v1 -=128;
  121.  
  122.       if (CCIR601)
  123.         {
  124.           y1 = ICCIRY(y1);
  125.           y2 = ICCIRY(y2);
  126.           y3 = ICCIRY(y3);
  127.           y4 = ICCIRY(y4);
  128.  
  129.           u1 = ICCIRUV(u1);
  130.           v1 = ICCIRUV(v1);
  131.         }
  132.  
  133.       temp=GETR(y1,u1,v1);
  134.       *(rgb1p++) = CLIP(temp);
  135.       temp=GETG(y1,u1,v1);
  136.       *(rgb1p++) = CLIP(temp);
  137.       temp=GETB(y1,u1,v1);
  138.       *(rgb1p++) = CLIP(temp);
  139.  
  140.       temp=GETR(y2,u1,v1);
  141.       *(rgb1p++) = CLIP(temp);
  142.       temp=GETG(y2,u1,v1);
  143.       *(rgb1p++) = CLIP(temp);
  144.       temp=GETB(y2,u1,v1);
  145.       *(rgb1p++) = CLIP(temp);
  146.  
  147.       temp=GETR(y3,u1,v1);
  148.       *(rgb2p++) = CLIP(temp);
  149.       temp=GETG(y3,u1,v1);
  150.       *(rgb2p++) = CLIP(temp);
  151.       temp=GETB(y3,u1,v1);
  152.       *(rgb2p++) = CLIP(temp);
  153.  
  154.       temp=GETR(y4,u1,v1);
  155.       *(rgb2p++) = CLIP(temp);
  156.       temp=GETG(y4,u1,v1);
  157.       *(rgb2p++) = CLIP(temp);
  158.       temp=GETB(y4,u1,v1);
  159.       *(rgb2p++) = CLIP(temp);
  160.  
  161.     }
  162.       fwrite(temprgb1,1,cols*3*sizeof(char),out);
  163.       fwrite(temprgb2,1,cols*3*sizeof(char),out);
  164.      }
  165. }
  166.  
  167. int
  168. main(argc, argv)
  169.      int argc;
  170.      char **argv;
  171. {
  172.   int i;
  173.   int CCIR601=0;
  174.   int width=352,height=240;
  175.   int suffixcount=0;
  176.   char *infile,*outfile;
  177.   char infiley[256];
  178.   char infileu[256];
  179.   char infilev[256];
  180.   FILE *out,*iny,*inu,*inv;
  181.  
  182.   if (argc<3)
  183.     {
  184.       printf("cyuv2ppm infile outfile [-iw width] [-ih height] [-z suffix]* [-CCIR601]\n");
  185.       printf("\n");
  186.       printf("width  = 352 by default, width of component input file\n");
  187.       printf("height = 240 by default, width of component input file\n");
  188.       printf("infile is the input yuv file; default infile.Y infile.U infile.V.\n");
  189.       printf("outfile is the output ppm file.\n");
  190.       printf("-z specifies alternate suffixes:\n");
  191.       printf("          e.g. cyuv2ppm inp out.ppm -z .y -z .cb -z .cr\n");
  192.       printf("          will input in.y, in.cb, in.cr, respectively\n");
  193.       printf("-CCIR601 specifies CCIR601 yuv space (default JFIF).\n");
  194.       exit(0);
  195.     }
  196.  
  197.   for(i=3;i<argc;i++)
  198.     {
  199.       if (!strcmp(argv[i],"-z"))
  200.     {
  201.       if (suffixcount==3)
  202.         {
  203.           printf("too many suffixes\n");
  204.           exit(0);
  205.         }
  206.       suffix[suffixcount++] = argv[++i];
  207.     }
  208.       else if (!strcmp(argv[i],"-iw"))
  209.     width = atoi(argv[++i]);
  210.       else if (!strcmp(argv[i],"-ih"))
  211.     height = atoi(argv[++i]);
  212.       else if (!strcmp(argv[i],"-CCIR601"))
  213.     CCIR601=1;
  214.       else
  215.     {
  216.       printf("unknown option: %s\n",argv[i]);
  217.       exit(0);
  218.     }
  219.     }
  220.  
  221.   infile = argv[1];
  222.   outfile = argv[2];
  223.   sprintf(infiley,"%s%s",infile,suffix[0]);
  224.   sprintf(infileu,"%s%s",infile,suffix[1]);
  225.   sprintf(infilev,"%s%s",infile,suffix[2]);
  226.  
  227.   if (!(out=fopen(outfile,"w")))
  228.     {
  229.       printf("cannot open file: %s\n",outfile);
  230.       exit(0);
  231.     }
  232.   if (!(iny=fopen(infiley,"r")))
  233.     {
  234.       printf("cannot open file: %s\n",infiley);
  235.       exit(0);
  236.     }
  237.   if (!(inu=fopen(infileu,"r")))
  238.     {
  239.       printf("cannot open file: %s\n",infileu);
  240.       exit(0);
  241.     }
  242.   if (!(inv=fopen(infilev,"r")))
  243.     {
  244.       printf("cannot open file: %s\n",infilev);
  245.       exit(0);
  246.     }
  247.   convertYUV2RGB(width,height,iny,inu,inv,out,CCIR601);
  248.   exit(0);
  249. }
  250.  
  251.